package com.gskj.educenter.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.gskj.commonutils.JwtUtils;
import com.gskj.educenter.entity.UcenterMember;
import com.gskj.educenter.service.IUcenterMemberService;
import com.gskj.educenter.utils.HttpClientUtils;
import com.gskj.educenter.utils.WechatPropUtils;
import com.gskj.servicebase.exceptionhandler.GuLiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.util.HashMap;

/**
 * @author :CodingFarmer_码农  Connor(康纳)_郭
 * @date : 08:22 20.5.22
 * @Company : http://www.gskj.com
 * @Version : 1.0
 */
@Controller
@CrossOrigin
@RequestMapping("/api/ucenter/wx")
@Slf4j
public class WeChatController {

    @Autowired
    private WechatPropUtils wechatPropUtils;

    @Autowired
    private IUcenterMemberService memberService;


    /**
     * 访问固定地址，生成二维码
     *
     * @return
     */
    @RequestMapping("/login")
    public String getWxCode() {

        // 微信开放平台授权baseUrl
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +  //%s 代表占位符 ?
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";

        // 对 redirectUrl进行编码  UTF-8
        String redirectUrl = wechatPropUtils.WX_OPEN_REDIRECT_URL;
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用 Stirng.format()对占位符 %s赋值
        String url = String.format(baseUrl,
                wechatPropUtils.WX_OPEN_APP_ID,
                redirectUrl,
                "gskj");
        // 请求生成微信二维码的 路径
        return "redirect:" + url;
    }

    /**
     * 当扫描 微信二维码后 跳转的回调方法。
     *
     * @return
     */
    @GetMapping("/callback")
    public String callback(@RequestParam("code") String code,
                           @RequestParam("state") String state) {
        try {
            // 1.
            // 获取code 值。 微信用户的临时id
            // 通过 携带code值等参数,去访问微信固定地址。并返回 accsess_token ,openid等信息

            //向认证服务器发送请求换取access_token
            String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" + // 固定地址
                    "?appid=%s" +
                    "&secret=%s" +
                    "&code=%s" +
                    "&grant_type=authorization_code";

            // 拼接 参数 appId,appSecret,code
            String accessTokenUrl = String.format(baseAccessTokenUrl,
                    wechatPropUtils.WX_OPEN_APP_ID,
                    wechatPropUtils.WX_OPEN_APP_SECRET,
                    code);

            // 通过HttpClientUtils 去请求 拼接好的微信url,并返回响应体
            String responseBody = HttpClientUtils.get(accessTokenUrl);
            log.info("body " + responseBody);
            /** json 字符串
             *  {
             *   "access_token":"33_3UkxHc3l5WM6kMHjN3wXuPBeC0fd8MFSV32GiIdvVofHzvQCFenGY5EgYfhDZLeMxvNDOrNJcjX9EEQeYgOpOPN-fkfXkCIH2ULLeciHNuY",
             *   "expires_in":7200,"refresh_token":"33_l_9QgPRaHgWba5Vt6Zcrwmi61EgTXlrFr4dh5uTmP17Rdx-bAxi2t8HQAuAeYe5l545NBXUuPaF9mq4CR_ujxWdMv-PKWLis2MiqAi_BfBI",
             *   "openid":"o3_SC57-IWLXiQCEAXUBhNFFvBjI",
             *   "scope":"snsapi_login",
             *   "unionid":"oWgGz1EGNU5EsfUOvBkY9PiTEwzY"
             *  }
             */
            // 将 responseBody 转为map形式
            Gson gson = new Gson();
            HashMap hashMap = gson.fromJson(responseBody, HashMap.class);
            // 通过键获取value
            String accessToken = (String) hashMap.get("access_token");
            String openId = (String) hashMap.get("openid");

            // 先根据openid 判断 用户信息是否存在数据表，如没有存在，再次发起请求 将获取到的用户信息解析 添加到数据表
            UcenterMember memberByOpenId = memberService.getMemberByOpenId(openId);
//            log.info(memberByOpenId.toString());

            // 判断 memberByOpenId=null 表示该用户未添加
            if (memberByOpenId == null) {

                // 拿着 accessToken,openId 去请求固定微信的地址，获取用户信息
                //访问微信的资源服务器，获取用户信息
                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=%s" +
                        "&openid=%s";

                String getUserInfoUrl = String.format(baseUserInfoUrl,
                        accessToken,
                        openId);
                //发送请求。
                String userInfoJsonStr = HttpClientUtils.get(getUserInfoUrl);
                log.info("userInfoJsonStr " + userInfoJsonStr);
                /**
                 * userInfoJsonStr
                 * {
                 *  "openid":"o3_SC57-IWLXiQCEAXUBhNFFvBjI",
                 *  "nickname":"阿达耐克AJ连锁（代理商）",
                 *  "sex":1,
                 *  "language":"zh_CN",
                 *  "city":"Anyang",
                 *  "province":"Henan",
                 *  "country":"CN",
                 *  "headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/RfI6z1tsvia0t8NKRH6ic2ibQ5EHKbUGIEsAoj783J6gLjpbYYk0s86YxkF0UPUVYdCowpGsdPlePKBFlgWkEQDwg\/132",
                 *  "privilege":[],
                 *  "unionid":"oWgGz1EGNU5EsfUOvBkY9PiTEwzY"
                 * }
                 */
                // 将返回的userInfoJsonStr 转为map
                HashMap userInfoMap = gson.fromJson(userInfoJsonStr, HashMap.class);
                String nickname = (String) userInfoMap.get("nickname"); // 昵称
                String userOpenId = (String) userInfoMap.get("openid"); // 微信id

                Double sex = (Double) userInfoMap.get("sex"); // 性别
                String headimgurl = (String) userInfoMap.get("headimgurl"); //头像

                // 执行添加
                memberByOpenId = new UcenterMember();
                memberByOpenId.setAvatar(headimgurl);
                memberByOpenId.setOpenid(userOpenId);

                // 将 微信接口返回的该死的 年龄为Double类型转为 Integer类型。Fuck You Tencent!
                int i = sex.intValue();
                log.info("i = " + i);
                memberByOpenId.setSex(i);
                memberByOpenId.setNickname(nickname);
                // 添加微信登陆的会员信息
                memberService.save(memberByOpenId);
            }
            // 通过 jwt 生成 token值，携带到 请求路路径中
            String jwtToken = JwtUtils.getJwtToken(memberByOpenId.getId(), memberByOpenId.getNickname());

            // 重定向到 前台首页
            return "redirect:http://localhost:3000?token=" + jwtToken;

        } catch (Exception e) {
            e.printStackTrace();
            throw new GuLiException(20001, "启用微信登陆服务失败！");
        }
    }
}
